﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Threading;

namespace wf_test_invoke
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private delegate string delegate_main_to_other_thread(string s);
        private event delegate_main_to_other_thread event_on_ui_request;
        public virtual string OnGetSNEvent(string s)
        {
            return event_on_ui_request?.Invoke(s);
        }

        private Test_thread_invoker test_thread_class;


        private string Test_func_invoke_from_ui_to_thread(string data_in)
        {
            Console.WriteLine("Test_func_invoke_from_ui_to_thread start");
            Test_thread_invoker.Print_current_thread();
            Console.WriteLine("Test_func_invoke_from_ui_to_thread end");
            return " ";
        }

        private void button_test_btn_Click(object sender, EventArgs e)
        {
            //test_thread_class.list_action_buffer.Add(Test_func_invoke_from_ui_to_thread);
            textBox_test_result.Text = OnGetSNEvent("112233");//event_on_ui_request("112233");
        }



        private void Test_thread_class_event_on_test_timeout(string message)
        {
            Console.WriteLine("Test_thread_class_event_on_test_timeout");
            //Test_thread_invoker.Print_current_thread();
            //textBox_test_result.Invoke(new Action(() =>
            //{
            //    textBox_test_result.Text = message;
            //    Test_thread_invoker.Print_current_thread();
            //}));
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Test_thread_invoker.Print_current_thread();
            test_thread_class = new Test_thread_invoker();
            test_thread_class.event_on_test_timeout += Test_thread_class_event_on_test_timeout;
            event_on_ui_request += test_thread_class.Other_thread_operation_test;
        }
    }

    public class Test_thread_invoker
    {
        public delegate void test_delegate(string message);
        public event test_delegate event_on_test_timeout;

        public int reload_timeout = 0;

        public Thread thread_working;
        public Dispatcher thread_dispather;

        //public Dispat

        public bool isThreadWorking = false;


        public List<Func<string, string>> list_action_buffer = new List<Func<string, string>>();

        public string Other_thread_operation_test(string s_in)
        {
            string ret = "";
            //do something
            thread_dispather.Invoke(new Action(() =>
            {
                ret = s_in.Replace("1", "2");
                Print_current_thread();
            }));
            //

            return ret;
        }


        ManualResetEventSlim started_Event = new ManualResetEventSlim();

        public Test_thread_invoker()
        {
            thread_working = new Thread(new ThreadStart(Test_thread_process));
            thread_working.Start();
            started_Event.WaitHandle.WaitOne();
            thread_dispather = Dispatcher.FromThread(thread_working);
            if (thread_dispather == null)
            {
                Console.WriteLine("dispather get error");
                return;
            }

            thread_dispather.BeginInvoke(new Action(() =>
            {
                Console.WriteLine("dispather thread start success");
                Print_current_thread();
            }));
        }

        public static void Print_current_thread()
        {
            var p = Process.GetCurrentProcess();
            Console.WriteLine(p.ProcessName.ToString() + " pid:" + p.Id.ToString() + " threadid:" + Thread.CurrentThread.ManagedThreadId);
        }

        public void Test_thread_process()
        {
            isThreadWorking = true;

            Print_current_thread();

            Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
            {
                started_Event.Set();
            }));

            Dispatcher.Run();

            Console.WriteLine("Dispacher run error?");
        }
    }
}
